var MeshVertex = (function MVClosure() {
    function MeshVertex() {
        this.m_Flag = 0;
        this.m_x = 0;
        this.m_y = 0;
        this.m_Clr = new Array(3);  //default rgb

        this.GetFlag = function () {
            return this.m_Flag;
        };
        this.GetPoint = function () {
            return [m_x, m_y];
        };
        this.GetRGB = function () {
            return this.m_Clr;
        };
    }

    MeshVertex.prototype.ParseJson2 = function (arrayData) {
        var meshVertex = this;
        meshVertex.m_Flag = arrayData[0];
        meshVertex.m_x = parseFloat(arrayData[1]);
        meshVertex.m_y = parseFloat(arrayData[2]);
        meshVertex.m_Clr = arrayData[3];
    };
    
    MeshVertex.prototype.ParseFromBin = function(rd) {
    	this.m_Flag = rd.readUint32();
    	this.m_x = rd.readFloat32();
    	this.m_y = rd.readFloat32();
    	for (var i = 0; i < 3; i++) {
    		this.m_Clr[i] = rd.readFloat32();
    	}
    };
    
    MeshVertex.prototype.createByJson = function (jsonDataForArrMeshVertex) {

        var arrMeshVertex = [];

        for (var jIndex = 0; jIndex < jsonDataForArrMeshVertex.length; jIndex++) {
            var tempMeshVertexJson = jsonDataForArrMeshVertex[jIndex];
            var meshVertex = new MeshVertex();
            meshVertex.ParseJson2(tempMeshVertexJson);
            meshVertex.prototype = null;
            arrMeshVertex[jIndex] = meshVertex;
        }
        return arrMeshVertex;
    };
    
    MeshVertex.prototype.CreateByBin = function(rd, nCount) {
    	var arrMeshVertex = [];
    	for (var i = 0; i < nCount; i++) {
    		var meshVertex = new MeshVertex();
    		meshVertex.ParseFromBin(rd);
    		meshVertex.prototype = null;
    		arrMeshVertex[i] = meshVertex;
    	}
    	return arrMeshVertex;
    };
    
    return new MeshVertex();
})();

function CoonPatchMesh() {
    this.m_nFlag = 0;
    this.m_arrPoints = [];
    this.m_nPointCount = 0;
    this.m_arrClr = [];

    this.GetFlag = function () {
        return this.m_nFlag;
    };
    this.GetPoint = function (i) {
        var x = parseFloat(this.m_arrPoints[2 * i]);
        var y = parseFloat(this.m_arrPoints[2 * i + 1]);
        return [x, y];
    };
    this.GetRGB = function (i) {
        var r = (this.m_arrClr[3 * i]);
        var g = (this.m_arrClr[3 * i + 1]);
        var b = (this.m_arrClr[3 * i + 2]);
        return [r, g, b];
    };
    this.ParseJson2 = function (arrayData) {
        var coonPatch = this;
        coonPatch.m_nFlag = arrayData[0];
				coonPatch.m_arrPoints = stringArr2NumArr(arrayData[2]);
				coonPatch.m_nPointCount = arrayData[1];
				coonPatch.m_arrClr = arrayData[3];
    };
    this.ParseFromBin = function(rd) {
    	this.m_nFlag = rd.readUint32();
    	this.m_nPointCount = rd.readInt32();
    	for (var i = 0; i < this.m_nPointCount; i++) {
    		this.m_arrPoints.push(rd.readFloat32());
    		this.m_arrPoints.push(rd.readFloat32());
    	}
    	for (var i = 0; i < 12; i++) {
    		this.m_arrClr.push(rd.readInt32());
    	}
    };
}
CoonPatchMesh.prototype.FromJson = function (jsonData) {
        var arrPatch = [];
        for (var jIndex = 0; jIndex < jsonData.length; jIndex++) {
            var tempJson = jsonData[jIndex];
            var patch = new CoonPatchMesh();
            patch.ParseJson2(tempJson);
            //patch.prototype = null;
            arrPatch[jIndex] = patch;
        }
        return arrPatch;
};
CoonPatchMesh.prototype.FromBin = function(rd, nCount) {
	var arrPatch = [];
	for (var i = 0; i < nCount; i++) {
		var patch = new CoonPatchMesh();
		patch.ParseFromBin(rd);
		arrPatch[i] = patch;
	}
	return arrPatch;
};

function ShadingPattern() {
	/** matrix from pattern to parent stream. */
    this.m_mtPattern2Form = new PDMatrix();
    this.m_mtParentMatrix = new PDMatrix();
	this.m_ShadingType = 0;
	this.m_BBox = [];
	this.m_BackGround = null;//must rgb,but this is optional,can be null;
	this.m_clrSpace = 1;  //1 for DEVICEGRAY,2 for DEVICERGB, 3 DEVICECMYK
//	this.m_isNamedClrSpace = true; //whether the m_clrSpace member is named space;
	this.m_function = [];
	this.m_nFuncs = 0;
	this.m_ID = 0;	//default number
	this.m_Domain = [];
   // this.m_Matrix = [1,0,0,1,0,0];
    this.m_DomainMatrix = new PDMatrix();
    this.m_Cooords = [];
    this.m_Extend = [];
    this.m_nBitsPerCoordinate = 0; //Valid values are 1, 2, 4, 8, 12, 16, 24, and 32;
    this.m_nBitsPerComponent = 0; //Valid values are 1, 2, 4, 8, 12, and 16
    this.m_nBitsPerFlag = 0; //Valid values for the edge flag are 0, 1, and 2;
    this.m_arrDecode = [];
	this.m_arrMeshVertex = [];//
	this.m_nVerticesPerRow = 0;
	this.m_arrCoonPatchs = [];
}



ShadingPattern.prototype.FromJson = function (jsonData) {
    var shadingPattern = new ShadingPattern();
    if(jsonData  instanceof Array){
    	shadingPattern.ParseJson(jsonData);
    }else{
    	shadingPattern.ParseJson(jsonData);
    }
    return shadingPattern;
};

function stringArr2NumArr(arr) {
    if (Object.prototype.toString.call(arr) === '[object Array]') {
        var arrNum = [];
        var n = arr.length;
        for (var i = 0; i < n; i++) {
            arrNum[i] = parseFloat(arr[i]);
        }
        return arrNum;
    }
    return [];
      
    
}
ShadingPattern.prototype.ParseJson = function (arrayData) {
    //var shadingType = this;
    this.m_ShadingType = arrayData[4];
    this.m_ID = arrayData[0];
    if (arrayData[2] != null) {
    	//shadingType.m_mtPattern2Form = new PDMatrix(); 
    	var P2FArr = stringArr2NumArr(arrayData[2]);
    	this.m_mtPattern2Form.Set(P2FArr[0],P2FArr[1],P2FArr[2],P2FArr[3],P2FArr[4],P2FArr[5]);
    }
    if (arrayData[3] != null) {
    	//shadingType.m_mtParentMatrix = new PDMatrix(); 
    	var prtArr = stringArr2NumArr(arrayData[3]);
    	this.m_mtParentMatrix.Set(prtArr[0],prtArr[1],prtArr[2],prtArr[3],prtArr[4],prtArr[5]);
    }
 if (arrayData[1] != null && arrayData[1].length > 0) this.m_BBox = stringArr2NumArr(arrayData[1]);

    switch (this.m_ShadingType) {
        case 1:
            {
                if (arrayData[9] != null && arrayData[9].length > 0) this.m_Domain = stringArr2NumArr(arrayData[9]);
                if (arrayData[10] != null && arrayData[10].length > 0) {
                	//shadingType.m_DomainMatrix = new PDMatrix(); 
                	var dmnArr = stringArr2NumArr(arrayData[10]);
                	this.m_DomainMatrix.Set(dmnArr[0],dmnArr[1],dmnArr[2],dmnArr[3],dmnArr[4],dmnArr[5]);
                }
                this.m_function = __LoadFuncs(arrayData[8]);
                this.m_nFuncs = arrayData[7];
            }
            break;
        case 2:
        case 3:
            {
                this.m_Cooords = stringArr2NumArr(arrayData[11]);
                if (arrayData[9] != null) this.m_Domain = stringArr2NumArr(arrayData[9]);
                this.m_nFuncs = arrayData[7];
                this.m_function = __LoadFuncs(arrayData[8]);
                if (arrayData[12] != null) this.m_Extend = arrayData[12];
            }
            break;
        case 4:
            {
                this.m_nBitsPerCoordinate = stringArr2NumArr(arrayData[13]);
                this.m_nBitsPerComponent = stringArr2NumArr(arrayData[14]);
                this.m_nBitsPerFlag = arrayData[15];
                this.m_arrDecode = stringArr2NumArr(arrayData[17]);
                this.m_nFuncs = arrayData[7];
                if (arrayData[8] != null) this.m_function = __LoadFuncs(arrayData[8]);
                this.m_arrMeshVertex = MeshVertex.createByJson(arrayData[18]); //result array
            }
            break;
        case 5:
            {
                this.m_nBitsPerCoordinate = stringArr2NumArr(arrayData[13]);
                this.m_nBitsPerComponent = stringArr2NumArr(arrayData[14]);
                this.m_nVerticesPerRow = arrayData[16];
                this.m_arrDecode = stringArr2NumArr(arrayData[17]);
                this.m_nFuncs = arrayData[7];
                if (arrayData[8] != null) this.m_function = __LoadFuncs(arrayData[8]);
                this.m_arrMeshVertex = MeshVertex.createByJson(arrayData[18]); //result array
            }
            break;
        case 6:
        case 7:
            {
                this.m_nBitsPerCoordinate = stringArr2NumArr(arrayData[13]);
                this.m_nBitsPerComponent = stringArr2NumArr(arrayData[14]);
                this.m_nBitsPerFlag = arrayData[15];
                this.m_arrDecode = stringArr2NumArr(arrayData[17]);
                this.m_nFuncs = arrayData[7];
                if (arrayData[8] != null) this.m_function = __LoadFuncs(arrayData[8]);
                this.m_arrCoonPatchs = CoonPatchMesh.prototype.FromJson(arrayData[19]);
            }
            break;
        default:
    }
    if (arrayData[5] != null) this.m_BackGround = arrayData[5];
    if(arrayData[6] != null) this.m_clrSpace = arrayData[6];
};


ShadingPattern.prototype.ParseFromBin = function (rd) {
    var nCnt;
    var tempArr = [];
    for (var i = 0; i < 4; i++) { this.m_BBox.push(rd.readFloat32()); }
    tempArr = [];
    for (var i = 0; i < 6; i++) { tempArr.push(rd.readFloat32()); }
    this.m_mtPattern2Form.Set(tempArr[0], tempArr[1], tempArr[2], tempArr[3], tempArr[4], tempArr[5]);
    tempArr = [];
    for (var i = 0; i < 6; i++) { tempArr.push(rd.readFloat32()); }
    this.m_mtParentMatrix.Set(tempArr[0], tempArr[1], tempArr[2], tempArr[3], tempArr[4], tempArr[5]);
    this.m_ShadingType = rd.readInt32();
    this.m_BackGround = rd.readUint32();
    this.m_clrSpace = rd.readByte();
    this.m_nFuncs = rd.readByte();
    if (this.m_nFuncs > 0) {
        this.m_function = __LoadFuncs_InBin(rd, this.m_nFuncs);
    }
    for (var i = 0; i < 4; i++) { this.m_Domain.push(rd.readFloat32()); }
    tempArr = [];
    for (var i = 0; i < 6; i++) { tempArr.push(rd.readFloat32()); }
    this.m_DomainMatrix.Set(tempArr[0], tempArr[1], tempArr[2], tempArr[3], tempArr[4], tempArr[5]);
    if (2 === this.m_ShadingType) {
        for (var i = 0; i < 4; i++) { this.m_Cooords.push(rd.readFloat32()); }
    }
    else if (3 === this.m_ShadingType) {
        for (var i = 0; i < 6; i++) { this.m_Cooords.push(rd.readFloat32()); }
    }
    this.m_Extend.push(rd.readByte());
    this.m_Extend.push(rd.readByte());
    this.m_nBitsPerCoordinate = rd.readByte();
    this.m_nBitsPerComponent = rd.readByte();
    this.m_nBitsPerFlag = rd.readByte();
    this.m_nVerticesPerRow = rd.readByte();
    nCnt = rd.readInt32();
    if (nCnt > 0) {
        for (var i = 0; i < nCnt; i++) { this.m_arrDecode.push(rd.readFloat32()); }
    };
    switch (this.m_ShadingType) {
        case 1:
            break;
        case 2:
        case 3:
            break;
        case 4:
            nCnt = rd.readInt32();
            this.m_arrMeshVertex = MeshVertex.CreateByBin(rd, nCnt);
            break;
        case 5:
            nCnt = rd.readInt32();
            this.m_arrMeshVertex = MeshVertex.CreateByBin(rd, nCnt * this.m_nVerticesPerRow);
            break;
        case 6:
        case 7:
            nCnt = rd.readInt32();
            this.m_arrCoonPatchs = CoonPatchMesh.prototype.FromBin(rd, nCnt);
            break;
    }
};


function setupInheritPrototype(subType, superType) {
	/*function F() {}
	F.prototype = superType.prototype;
	var prototype = new F();
	prototype.constructor = subType;
	subType.prototype = prototype;*/
	
	//Modeifyed by haipeng_yang 2013-08-26 begin
	var prototype = new superType();
	prototype.constructor = subType;
	subType.prototype = prototype;
	//Modeifyed by haipeng_yang 2013-08-26 end
}
